import type { UploadProps } from "antd";
import { message, Typography } from "antd";
import Dragger from "antd/es/upload/Dragger";
import type { ReactElement } from "react";
import { commonService } from "@/api/services/commonService";
import { Iconify } from "../icon";
import { StyledUploadBox } from "./styles";

interface Props extends Omit<UploadProps, "action" | "customRequest"> {
	placeholder?: ReactElement;
	value?: string;
	onChange?: (value: string) => void;
}

const getFileIcon = (mimetype: string) => {
	if (mimetype.startsWith("image/")) {
		return "eva:image-fill";
	}
	if (mimetype.startsWith("video/")) {
		return "eva:video-fill";
	}
	if (mimetype.startsWith("audio/")) {
		return "eva:music-fill";
	}
	if (
		mimetype === "application/pdf" ||
		mimetype === "application/msword" ||
		mimetype.includes("officedocument")
	) {
		return "eva:file-text-fill";
	}
	if (mimetype.includes("zip") || mimetype.includes("rar")) {
		return "eva:archive-fill";
	}
	return "eva:file-fill";
};

const getFileTypeFromUrl = (url: string) => {
	const extension = url.split(".").pop()?.toLowerCase();
	switch (extension) {
		case "jpg":
		case "jpeg":
		case "png":
		case "gif":
		case "webp":
			return "image/" + extension;
		case "mp4":
		case "webm":
			return "video/" + extension;
		case "mp3":
		case "wav":
			return "audio/" + extension;
		case "pdf":
			return "application/pdf";
		case "doc":
		case "docx":
			return "application/msword";
		case "zip":
		case "rar":
			return "application/" + extension;
		default:
			return "application/octet-stream";
	}
};

export function UploadBox({ placeholder, value, onChange, ...other }: Props) {
	const customRequest = async (options: any) => {
		const { file, onSuccess, onError } = options;
		try {
			const data = await commonService.uploadFile(file);
			onSuccess();
			onChange?.(data.url);
		} catch (error) {
			message.error("上传失败");
			onError();
		}
	};

	const renderPreview = () => {
		if (!value) {
			return <Iconify icon="eva:cloud-upload-fill" size={28} />;
		}

		const mimetype = getFileTypeFromUrl(value);
		const isImage = mimetype.startsWith("image/");
		const filename = value.split("/").pop() || "";

		if (isImage) {
			return <img src={value} alt="" className="h-full w-full object-cover" />;
		}

		return (
			<div className="flex flex-col items-center justify-center">
				<Iconify icon={getFileIcon(mimetype)} size={28} />
				<Typography.Text
					className="mt-2 w-full"
					ellipsis={{ tooltip: filename }}
					style={{ maxWidth: 120 }}
				>
					{filename}
				</Typography.Text>
			</div>
		);
	};

	return (
		<StyledUploadBox>
			<Dragger {...other} customRequest={customRequest} showUploadList={false}>
				<div className="opacity-60 hover:opacity-50">
					{placeholder || (
						<div className="m-auto flex h-16 w-16 items-center justify-center">
							{renderPreview()}
						</div>
					)}
				</div>
			</Dragger>
		</StyledUploadBox>
	);
}
